package com.fivefu.core.skyeye.event.services.callable;

import com.alibaba.fastjson.JSONObject;
import com.fivefu.core.data.services.DbFfskyeyeChannelService;
import com.fivefu.core.skyeye.event.entity.DbAiScene;
import com.fivefu.core.skyeye.event.entity.DbAiSceneCamera;
import com.fivefu.core.skyeye.event.entity.DbAiSceneNode;
import com.fivefu.core.skyeye.event.entity.DbAiSceneType;
import com.fivefu.core.skyeye.event.services.*;
import com.fivefu.core.skyeye.event.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class EditOnOff implements Supplier<String> {
    private String sceneCode;
    private List<String> cameraList;
    private Integer enable;
    private DbAiSceneService dbAiSceneService;
    private DbAiSceneCameraService dbAiSceneCameraService;
    private DbAiSceneTypeService dbAiSceneTypeService;
    private MimirEventService mimirEventService;
    private DbFfskyeyeChannelService dbFfskyeyeChannelService;
    private DbAiSceneNodeService dbAiSceneNodeService;
    private String streamType;

    private Logger logger = LoggerFactory.getLogger(EditOnOff.class);

    public EditOnOff(String sceneCode,List<String> cameraList,Integer enable,DbAiSceneService dbAiSceneService,DbAiSceneCameraService dbAiSceneCameraService,DbAiSceneTypeService dbAiSceneTypeService,MimirEventService mimirEventService,DbFfskyeyeChannelService dbFfskyeyeChannelService,DbAiSceneNodeService dbAiSceneNodeService,String streamType){
        this.sceneCode = sceneCode;
        this.cameraList = cameraList;
        this.enable = enable;
        this.dbAiSceneService = dbAiSceneService;
        this.dbAiSceneCameraService = dbAiSceneCameraService;
        this.dbAiSceneTypeService = dbAiSceneTypeService;
        this.mimirEventService = mimirEventService;
        this.dbFfskyeyeChannelService = dbFfskyeyeChannelService;
        this.dbAiSceneNodeService = dbAiSceneNodeService;
        this.streamType = streamType;
    }
    @Override
    public String get() {
        try {
            Integer cvId = getCvId(sceneCode);//场景类型
            //其他开启场景
            List<String> otherSceneList = dbAiSceneService.getCameraCodes(sceneCode);
            //其他开启场景下的开启探头集合
            List<String> openCameraList = dbAiSceneCameraService.getCamera(otherSceneList);
            //当前场景需要开启/关闭的探头
            if (cameraList == null || cameraList.size() == 0){
                List<String> sceneList = new ArrayList<>();
                sceneList.add(sceneCode);
                //该场景下开启的探头
                cameraList = dbAiSceneCameraService.getCamera(sceneList);
            }

            //其他场景下开启的探头唯一标识集合
            Set<String> openCameraSet = new HashSet<>();
            if (openCameraList != null && openCameraList.size() > 0){
                openCameraSet = openCameraList.stream().collect(Collectors.toSet());
            }

            List<String> open = new ArrayList<>();//只需开关识别的探头
            List<String> others = new ArrayList<>();//需要全部开关的探头
            for (String code : cameraList) {
                if (openCameraSet.contains(code)){
                    open.add(code);
                }else{
                    others.add(code);
                }
            }
            turnOffDiscernment(sceneCode,open,others,cvId,enable,streamType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过场景唯一标识获得场景类型
     * @param sceneCode
     * @return
     * @throws Exception
     */
    public Integer getCvId(String sceneCode){
        //通过场景唯一标识获取场景信息
        DbAiScene dbAiScene = dbAiSceneService.querySceneByCode(sceneCode);
        String cvType = dbAiScene.getCvType();
        DbAiSceneType dbAiSceneType = dbAiSceneTypeService.querySceneTypeByCvId(Integer.valueOf(cvType));
        Integer cvId = dbAiSceneType.getCvId();
        return cvId;
    }

    /**
     * 开启/关闭识别
     * @param sceneCode 场景编号
     * @param only 开启/关闭识别
     * @param all 开启/关闭切片
     * @param cvId 识别标识
     * @param enable 是否开启(0:否,1:是)
     */
    public void turnOffDiscernment(String sceneCode,List<String> only,List<String> all,Integer cvId,Integer enable,String streamType){
        for (String camera : only) {
            editDiscern(sceneCode,camera,cvId,enable);//关闭/开启识别
        }

        if (enable.equals(0)){//关闭
            for (String camera : all) {
                editDiscern(sceneCode,camera,cvId,enable);//关闭识别
                editSlice(sceneCode,camera,enable);//关闭切片
                editStream(camera,enable,streamType);//关闭流
            }
        }else if(enable.equals(1)){//开启
            for (String camera : all) {
                editStream(camera,enable,streamType);//开启流
                editSlice(sceneCode,camera,enable);//开启切片
                editDiscern(sceneCode,camera,cvId,enable);//开启识别
            }
        }
    }

    /**
     * 编辑识别
     * @param sceneCode 场景唯一标识
     * @param cameraCode 探头唯一标识
     * @param cvId 场景类型
     * @param enable 是否开启（0：否 1：是）
     */
    public void editDiscern(String sceneCode,String cameraCode,Integer cvId,Integer enable){
        //场景探头相关信息
        DiscernmentBean discernmentBean = getDiscernmentBean(sceneCode, cameraCode);
        if (cvId.equals(4)){//识别
            SceneDataBean sceneDataBean = mimirEventService.queryScene(cameraCode, cvId);
            if (sceneDataBean != null){
                mimirEventService.editScene("modify",cameraCode,cvId,enable,discernmentBean);
            }else if (enable.equals(1)){
                mimirEventService.editScene("add",cameraCode,cvId,enable,discernmentBean);
            }

        }else {
            IllegalCameraBean illegalCameraBean = mimirEventService.queryIllegalCameraStream(cameraCode, cvId);
            if (illegalCameraBean != null){
                mimirEventService.editIllegalCameraStream("modify",cameraCode,cvId,enable,discernmentBean);
            }else if(enable.equals(1)){
                mimirEventService.editIllegalCameraStream("add",cameraCode,cvId,enable,discernmentBean);
            }
        }
    }

    /**
     * 编辑切片
     * @param sceneCode 场景唯一标识
     * @param cameraCode 探头唯一标识
     * @param enable 是否开启（0：否 1：是）
     */
    public void editSlice(String sceneCode,String cameraCode,Integer enable){
        //场景探头相关信息
        DiscernmentBean discernmentBean = getDiscernmentBean(sceneCode, cameraCode);
        StreamSliceBean streamSliceBean = mimirEventService.queryCameraStreamSlice(cameraCode);//切片信息
        if (streamSliceBean != null){
            mimirEventService.editCameraStreamSlice("modify",cameraCode,enable,discernmentBean);
        }else if (enable.equals(1)){
            mimirEventService.editCameraStreamSlice("add",cameraCode,enable,discernmentBean);
        }
    }

    /**
     * 编辑流
     * @param cameraCode
     * @param enable
     */
    public void editStream(String cameraCode,Integer enable,String streamType){
        //探头流地址  //测试环境下hls
        String url = dbFfskyeyeChannelService.queryUrlByChannelCode(cameraCode, streamType, null);
        JSONObject jsonObject = JSONObject.parseObject(url);
        String streamUrl = jsonObject.get("url").toString();
        StreamDataBean streamDataBean = mimirEventService.queryCameraStream(cameraCode);//流信息
        if (streamDataBean != null){
            mimirEventService.editCameraStream("modify",cameraCode,streamUrl,enable);
        }else if (enable.equals(1)){
            mimirEventService.editCameraStream("add",cameraCode,streamUrl,enable);
        }
    }

    /**
     * 场景探头相关信息
     * @param sceneCode 场景唯一标识
     * @param cameraCode 探头唯一标识
     * @return
     */
    public DiscernmentBean getDiscernmentBean(String sceneCode, String cameraCode){
        DbAiSceneCamera sceneCamera = dbAiSceneCameraService.querySceneCamera(sceneCode, cameraCode);
        DbAiScene scene = dbAiSceneService.querySceneByCode(sceneCode);
        DbAiSceneNode eventNode = null;
        if (sceneCamera.getEventNode() != null){
            eventNode = dbAiSceneNodeService.querySceneNodeById(sceneCamera.getEventNode());
        }

        DbAiSceneNode sliceNode = null;
        if (sceneCamera.getSliceNode() != null){
            sliceNode = dbAiSceneNodeService.querySceneNodeById(sceneCamera.getSliceNode());

        }

        DiscernmentBean bean = new DiscernmentBean();
        bean.setCameraValidTime(sceneCamera.getCameraValidTime());
        bean.setContinuedTime(scene.getContinuedTime());
        bean.setCvParam(sceneCamera.getCvParam());
        bean.setEventNodeName(eventNode.getNodeName());
        bean.setScopeArea(sceneCamera.getScopeArea());
        bean.setSliceNodeName(sliceNode.getNodeName());

        return bean;
    }
}
